<template>
  <div class="comment-item" :class="{ 'is-reply': isReply }">
    <div class="avatar">
      <img :src="comment.avatar" :alt="comment.nickname">
    </div>
    <div class="comment-content">
      <div class="comment-header">
        <div class="user-info">
          <span class="nickname" :class="{ 'is-author': isAuthor }">
            {{ comment.nickname }}
            <span v-if="isAuthor" class="author-tag">作者</span>
          </span>
          <span v-if="comment.targetNickname" class="reply-to">
            回复 @{{ comment.targetNickname }}
          </span>
        </div>
        <time class="time" :title="formatFullDate(comment.createTime)">
          {{ formatDate(comment.createTime) }}
        </time>
      </div>

      <div class="comment-text">{{ comment.content }}</div>

      <div class="comment-footer">
        <div class="action-btns">
          <button
            class="action-btn like-btn"
            :class="{ 'liked': comment.isLike }"
            @click="() => emit('like', { id: comment.id, type: isReply ? 2 : 1 })"
          >
            <PhThumbsUp :size="16" :weight="comment.isLike ? 'fill' : 'regular'" />
            <span class="like-count">{{ comment.likes }}</span>
          </button>
          <button
            class="action-btn dislike-btn"
            :class="{ 'disliked': comment.isDisLike }"
            @click="() => emit('dislike', { id: comment.id, type: isReply ? 2 : 1 })"
          >
            <PhThumbsDown :size="16" :weight="comment.isDisLike ? 'fill' : 'regular'" />
            <span class="dislike-count">{{ comment.dislikes }}</span>
          </button>
          <button class="action-btn reply-btn" @click="handleReply">
            <PhChat :size="16" />
            回复
          </button>
        </div>
      </div>

      <!-- 二级评论列表 -->
      <div v-if="!isReply && comment.replyList?.length" class="reply-list">
        <!-- 默认只显示第一条回复 -->
        <div v-if="!showAllReplies" class="reply-item" :style="comment.replyList?.length === 1 ? 'border-bottom: 0' : 'border-bottom:1px solid #e5e7eb'">
          <div class="avatar">
            <img :src="comment.replyList[0].avatar" :alt="comment.replyList[0].nickname">
          </div>
          <div class="reply-content">
            <div class="reply-header">
              <span class="nickname" :class="{ 'is-author': comment.replyList[0].userId === articleAuthorId }">
                {{ comment.replyList[0].nickname }}
                <span v-if="comment.replyList[0].userId === articleAuthorId" class="author-tag">作者</span>
              </span>
              <span class="reply-to">
                回复 @{{ comment.replyList[0].targetNickname }}
              </span>
            </div>
            <div class="reply-text">{{ comment.replyList[0].content }}</div>
            <div class="reply-footer">
              <time class="time">{{ formatDate(comment.replyList[0].createTime) }}</time>
              <div class="action-btns">
                <button
                  class="action-btn like-btn"
                  :class="{ 'liked': comment.replyList[0].isLike }"
                  @click="() => emit('like', { id: comment.replyList[0].id, type: 2 })"
                >
                  <PhThumbsUp :size="14" :weight="comment.replyList[0].isLike ? 'fill' : 'regular'" />
                  <span class="like-count">{{ comment.replyList[0].likes }}</span>
                </button>
                <button
                  class="action-btn dislike-btn"
                  :class="{ 'disliked': comment.replyList[0].isDisLike }"
                  @click="() => emit('dislike', { id: comment.replyList[0].id, type: 2 })"
                >
                  <PhThumbsDown :size="14" :weight="comment.replyList[0].isDisLike ? 'fill' : 'regular'" />
                  <span class="dislike-count">{{ comment.replyList[0].dislikes }}</span>
                </button>
                <button class="action-btn reply-btn" @click="() => handleReplyToReply(comment.replyList[0])">
                  回复
                </button>
              </div>
            </div>
          </div>
        </div>

        <!-- 展开按钮 -->
        <div v-if="!showAllReplies && comment.replyList.length > 1" class="view-more-replies">
          <button
            class="view-more-btn"
            @click="expandReplies"
            :disabled="isAnimating"
          >
            <PhCaretDown :size="14" class="icon" />
            {{ `查看全部 ${comment.replyList.length} 条回复` }}
          </button>
        </div>

        <!-- 所有回复列表 -->
        <div
          v-show="showAllReplies"
          class="all-replies"
          ref="repliesRef"
        >
          <TransitionGroup
            name="reply-list"
            tag="div"
            :css="false"
            @before-enter="beforeEnter"
            @enter="enter"
            @leave="leave"
          >
            <div
              v-for="reply in comment.replyList"
              :key="reply.id"
              class="reply-item"
            >
              <div class="avatar">
                <img :src="reply.avatar" :alt="reply.nickname">
              </div>
              <div class="reply-content">
                <div class="reply-header">
                  <span class="nickname" :class="{ 'is-author': reply.userId === articleAuthorId }">
                    {{ reply.nickname }}
                    <span v-if="reply.userId === articleAuthorId" class="author-tag">作者</span>
                  </span>
                  <span class="reply-to">
                    回复 @{{ reply.targetNickname }}
                  </span>
                </div>
                <div class="reply-text">{{ reply.content }}</div>
                <div class="reply-footer">
                  <time class="time">{{ formatDate(reply.createTime) }}</time>
                  <div class="action-btns">
                    <button
                      class="action-btn like-btn"
                      :class="{ 'liked': reply.isLike }"
                      @click="() => emit('like', { id: reply.id, type: 2 })"
                    >
                      <PhThumbsUp :size="14" :weight="reply.isLike ? 'fill' : 'regular'" />
                      <span class="like-count">{{ reply.likes }}</span>
                    </button>
                    <button
                      class="action-btn dislike-btn"
                      :class="{ 'disliked': reply.isDisLike }"
                      @click="() => emit('dislike', { id: reply.id, type: 2 })"
                    >
                      <PhThumbsDown :size="14" :weight="reply.isDisLike ? 'fill' : 'regular'" />
                      <span class="dislike-count">{{ reply.dislikes }}</span>
                    </button>
                    <button class="action-btn reply-btn" @click="() => handleReplyToReply(reply)">
                      回复
                    </button>
                  </div>
                </div>
              </div>
            </div>
          </TransitionGroup>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue';
import type { Comment, Reply } from '@/types/comment';
import { PhThumbsUp, PhThumbsDown, PhChat, PhCaretDown } from '@phosphor-icons/vue';
import { formatDate } from '@/utils/date';
import gsap from 'gsap';

const props = defineProps<{
  comment: Comment;
  isReply?: boolean;
  articleAuthorId: string;
  parentComment?: Comment;
}>();

const emit = defineEmits<{
  (e: 'reply', data: { comment: Comment | Reply; parentComment?: Comment }): void;
  (e: 'like', data: { id: string; type: 1 | 2 }): void;
  (e: 'dislike', data: { id: string; type: 1 | 2 }): void;
}>();

const repliesRef = ref<HTMLElement | null>(null);
const showAllReplies = ref(false);
const isAnimating = ref(false);
const isAuthor = computed(() => props.comment.userId === props.articleAuthorId);

// 动画相关方法
const beforeEnter = (el: Element) => {
  gsap.set(el, {
    opacity: 0,
    y: 20,
    scale: 0.95
  });
};

const enter = (el: Element, done: () => void) => {
  gsap.to(el, {
    opacity: 1,
    y: 0,
    scale: 1,
    duration: 0.4,
    ease: 'back.out(1.4)',
    onComplete: () => {
      // 清除内联样式
      gsap.set(el, {
        clearProps: 'all'
      });
      done();
    }
  });
};

const leave = (el: Element, done: () => void) => {
  gsap.to(el, {
    opacity: 0,
    y: -20,
    scale: 0.95,
    duration: 0.3,
    ease: 'power2.in',
    onComplete: () => {
      // 清除内联样式
      gsap.set(el, {
        clearProps: 'all'
      });
      done();
    }
  });
};

// 展开动画
const expandReplies = async () => {
  if (!repliesRef.value || isAnimating.value) return;

  isAnimating.value = true;
  showAllReplies.value = true;

  gsap.fromTo(repliesRef.value,
    {
      height: 0,
      opacity: 0,
      overflow: 'hidden'
    },
    {
      height: 'auto',
      opacity: 1,
      duration: 0.5,
      ease: 'power2.inOut',
      onComplete: () => {
        gsap.set(repliesRef.value, { overflow: 'visible' });
        isAnimating.value = false;
      }
    }
  );
};

const handleReply = () => {
  emit('reply', { comment: props.comment });
};

const handleReplyToReply = (reply: Reply) => {
  emit('reply', {
    comment: reply,
    parentComment: props.comment
  });
};

const formatFullDate = (dateStr: string) => {
  return new Date(dateStr).toLocaleString('zh-CN', {
    year: 'numeric',
    month: 'long',
    day: 'numeric',
    hour: '2-digit',
    minute: '2-digit'
  });
};
</script>

<style scoped lang="less">
.comment-item {
  padding: 20px 0;
  display: flex;
  gap: 16px;
  border-bottom: 1px solid #e5e7eb;

  &:last-child {
    border-bottom: none;
  }

  .avatar {
    flex-shrink: 0;

    img {
      width: 40px;
      height: 40px;
      border-radius: 50%;
      object-fit: cover;
      transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);

      &:hover {
        transform: scale(1.05);
      }
    }
  }

  .comment-content {
    flex: 1;
    min-width: 0;

    .comment-header {
      display: flex;
      align-items: center;
      justify-content: space-between;
      margin-bottom: 8px;

      .user-info {
        display: flex;
        align-items: center;
        gap: 8px;

        .nickname {
          font-size: 15px;
          font-weight: 500;
          color: #1f2937;

          &.is-author {
            color: #3b82f6;
          }

          .author-tag {
            display: inline-block;
            padding: 2px 6px;
            background: #eff6ff;
            color: #3b82f6;
            border-radius: 4px;
            font-size: 12px;
            font-weight: normal;
            margin-left: 6px;
            transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);

            &:hover {
              background: #3b82f6;
              color: #fff;
              transform: scale(1.05);
            }
          }
        }

        .reply-to {
          color: #6b7280;
          font-size: 14px;
        }
      }

      .time {
        color: #9ca3af;
        font-size: 13px;
      }
    }

    .comment-text {
      font-size: 15px;
      line-height: 1.6;
      color: #1f2937;
      word-wrap: break-word;
      margin: 8px 0;
    }

    .comment-footer {
      margin-top: 12px;

      .action-btns {
        display: flex;
        gap: 16px;

        .action-btn {
          display: flex;
          align-items: center;
          gap: 6px;
          padding: 4px 8px;
          border: none;
          background: none;
          color: #6b7280;
          font-size: 14px;
          cursor: pointer;
          border-radius: 4px;
          transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);

          &:hover {
            color: #3b82f6;
            transform: translateY(-1px);
          }

          &:active {
            transform: translateY(0);
          }

          &.liked {
            color: #3b82f6;
          }

          &.disliked {
            color: #ef4444;
          }
        }
      }
    }

    .reply-list {
      margin-top: 16px;
      background: #f9fafb;
      border-radius: 8px;
      padding: 8px 16px;

      .reply-item {
        display: flex;
        gap: 12px;
        padding: 12px;
        border-bottom: 1px solid #e5e7eb;
        border-radius: 6px;
        will-change: transform;
        transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);

        &:last-child {
          border-bottom: none;
        }

        &:hover {
          background: rgba(59, 130, 246, 0.04);
          transform: translateX(4px);

          .avatar img {
            transform: scale(1.05);
          }

          .action-btns .action-btn {
            opacity: 1;
            transform: translateX(0);
          }
        }

        .avatar img {
          width: 32px;
          height: 32px;
          border-radius: 50%;
          transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
        }

        .reply-content {
          flex: 1;
          min-width: 0;

          .reply-header {
            display: flex;
            align-items: center;
            gap: 8px;
            margin-bottom: 4px;

            .nickname {
              font-size: 14px;
              font-weight: 500;
              color: #1f2937;

              &.is-author {
                color: #3b82f6;
              }

              .author-tag {
                display: inline-block;
                padding: 1px 4px;
                background: #eff6ff;
                color: #3b82f6;
                border-radius: 4px;
                font-size: 12px;
                font-weight: normal;
                margin-left: 4px;
                transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);

                &:hover {
                  background: #3b82f6;
                  color: #fff;
                  transform: scale(1.05);
                }
              }
            }

            .reply-to {
              color: #6b7280;
              font-size: 13px;
            }
          }

          .reply-text {
            font-size: 14px;
            line-height: 1.6;
            color: #1f2937;
            word-wrap: break-word;
          }

          .reply-footer {
            display: flex;
            align-items: center;
            justify-content: space-between;
            margin-top: 8px;

            .time {
              color: #9ca3af;
              font-size: 12px;
            }

            .action-btns {
              display: flex;
              gap: 12px;

              .action-btn {
                display: flex;
                align-items: center;
                gap: 4px;
                padding: 2px 6px;
                border: none;
                background: none;
                color: #6b7280;
                font-size: 13px;
                cursor: pointer;
                border-radius: 4px;
                opacity: 0.6;
                transform: translateX(-4px);
                transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);

                &:hover {
                  color: #3b82f6;
                  transform: translateY(-1px) translateX(0);
                  opacity: 1;
                }

                &:active {
                  transform: translateY(0) translateX(0);
                }

                &.liked {
                  color: #3b82f6;
                  opacity: 1;
                  transform: none;
                }

                &.disliked {
                  color: #ef4444;
                  opacity: 1;
                  transform: none;
                }
              }
            }
          }
        }
      }

      .view-more-replies {
        margin-top: 12px;
        text-align: center;

        .view-more-btn {
          display: flex;
          align-items: center;
          justify-content: center;
          gap: 4px;
          width: 100%;
          padding: 8px;
          border: none;
          background: #f1f5f9;
          color: #3b82f6;
          font-size: 14px;
          border-radius: 6px;
          cursor: pointer;
          transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
          will-change: transform;

          &:hover {
            background: #e2e8f0;
            transform: translateY(-1px);

            .icon {
              transform: translateY(2px) scale(1.1);
            }
          }

          &:active {
            transform: translateY(0);
          }

          &:disabled {
            opacity: 0.7;
            cursor: not-allowed;
          }

          .icon {
            transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
          }
        }
      }

      .all-replies {
        margin-top: 12px;
        will-change: transform, opacity, height;
      }
    }
  }
}

@media (max-width: 768px) {
  .comment-item {
    padding: 16px 0;

    .reply-list {
      margin: 12px 0;
      border-radius: 0;

      .reply-item {
        padding: 12px 16px;

        &:hover {
          transform: none;
          background: rgba(59, 130, 246, 0.04);
        }
      }
    }
  }
}
</style>
